home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / print / gs261sr1.zip / GDEVDFAX.C < prev    next >
C/C++ Source or Header  |  1993-05-19  |  25KB  |  763 lines

  1. /*
  2.  *    Copyright 1992 DigiBoard, Inc. All rights reserved
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software and its
  5.  * documentation for any purpose and without fee is hereby granted.
  6.  * This software is provided "as is" without express or implied warranty.
  7.  */
  8. /*
  9.  * 5/19/93 modified by L. Peter Deutsch, Aladdin Enterprises,
  10.  *   for compatibility with Ghostscript 2.6.1.
  11.  */
  12.  
  13. /* gdevdfax.c */
  14. /* DigiBoard, Inc. DigiFAX driver for Ghostscript. */
  15.  
  16. #include "gdevprn.h"
  17. #include "gdevdfg3.h"
  18.  
  19. #ifdef __PROTOTYPES__
  20. #    define PROTO_ARGS(X)    X
  21. #else
  22. #    define PROTO_ARGS(X)    ()
  23. #endif
  24.  
  25. /*************************************************************************
  26.  *    Format of page header in PC Research "group_3" FAX file
  27.  *
  28.  *    Note that all "shorts" are stored LSB in lowest byte address
  29.  *************************************************************************/
  30. typedef struct
  31. {
  32.     char    magic[24];
  33. } FAXBREAK;
  34.  
  35. #define    FAXMAGIC    "\000PC Research, Inc\000\000\000\000\000\000"
  36.     
  37. typedef struct
  38. {
  39. /*24*/    short    pages;        /* Number of pages in file */
  40. /*26*/    short    pagenum;
  41. /*28*/    char    msbfirst;    /* Coding used in file for codewords */
  42.                 /* MUST be set to 1, meaning the codewords */
  43.                 /* are filled starting with the most */
  44.                 /* significant bit */
  45. /*29*/    char    hires;        /* Set to 1 for Hi resolution, else 0 */
  46. /*30*/    char    dirty;        /* File may contain T.4 errors if 1, else 0 */
  47.                 /* e.g. it was received by FAX, not created */
  48.                 /* by a program */
  49. /*31*/    char    reservedc;
  50. /*32*/    short    reserved[12];
  51. } FAXINFO;
  52.  
  53. #define    OFFSET_PAGES    24
  54.  
  55. typedef struct
  56. {
  57.     char    jt0;
  58.     char    jthires;    /* Set to 0x40 for Hi resolution, else 0 */
  59.     char    jt2;
  60.     char    jt3;
  61.     char    jt4;
  62.     char    jt5;
  63.     char    jt6;
  64.     char    jt7;
  65. } JTINFO;
  66.  
  67. /*
  68.  *    This appears before each page in a FAX file
  69.  */
  70. typedef struct
  71. {
  72.     FAXBREAK    id;
  73.     FAXINFO        info;
  74.     JTINFO        jtinfo;
  75. } FAXHDR;
  76.  
  77. /**********************************************************************/
  78. /*
  79.  *    Generic fax output library
  80.  */
  81. /**********************************************************************/
  82.  
  83. typedef struct
  84. {
  85.     FILE        *fp;
  86.     int        fax_byte;
  87.     int        fax_weight;
  88.     int        pages;
  89. } FAXOUT;
  90.  
  91. private FAXOUT    *faxout_open PROTO_ARGS((char *));
  92. private FAXOUT    *faxout_open_fp PROTO_ARGS((FILE *));
  93. private int    faxout_begin_page PROTO_ARGS((FAXOUT *, int));
  94. private int    faxout_eolcode PROTO_ARGS((FAXOUT *));
  95. private int    faxout_end_page PROTO_ARGS((FAXOUT *));
  96. private int    faxout_close PROTO_ARGS((FAXOUT *));
  97. private unsigned short fax_ushort PROTO_ARGS((unsigned short));
  98. private void    tofax();
  99.  
  100. private void putwhitespan();
  101. private void putblackspan();
  102. private void putcode();
  103. private void puteol();
  104. private void putbit();
  105. private void flushbits();
  106.  
  107. /*************************************************************************
  108.     Redefine the device descriptor
  109.  *************************************************************************/
  110. struct gx_device_dfax_s {
  111.     gx_device_common;
  112.     gx_prn_device_common;
  113.     FAXOUT    *fax;
  114. };
  115. typedef struct gx_device_dfax_s gx_device_dfax;
  116.  
  117. /* The device descriptor */
  118. #define X_DPI 204
  119. #define Y_DPI 196
  120. #define LINE_SIZE ((X_DPI * 85 / 10 + 7) / 8)    /* bytes per line */
  121.  
  122. private dev_proc_open_device(dfax_prn_open);
  123. private dev_proc_print_page(dfax_print_page);
  124. private dev_proc_close_device(dfax_prn_close);
  125.  
  126. gx_device_procs dfax_std_procs =
  127.     prn_procs(dfax_prn_open, gdev_prn_output_page, dfax_prn_close);
  128.  
  129. gx_device_dfax gs_dfaxhigh_device =
  130. {    prn_device_std_body(
  131.         gx_device_dfax,
  132.         dfax_std_procs,
  133.         "dfaxhigh",
  134.         85,            /* width_10ths, 8.5" */
  135.         110,            /* height_10ths, 11" */
  136.         X_DPI, Y_DPI,
  137.         0,0,0,0,        /* margins */
  138.         1,
  139.         dfax_print_page
  140.     )
  141. };
  142.  
  143. gx_device_dfax gs_dfaxlow_device =
  144. {    prn_device_std_body(
  145.         gx_device_dfax,
  146.         dfax_std_procs,
  147.         "dfaxlow",
  148.         85,            /* width_10ths, 8.5" */
  149.         110,            /* height_10ths, 11" */
  150.         X_DPI, Y_DPI/2,
  151.         0,0,0,0,        /* margins */
  152.         1,
  153.         dfax_print_page
  154.     )
  155. };
  156.  
  157. /*************************************************************************
  158.     Driver entry points
  159.  *************************************************************************/
  160.  
  161. private int
  162. dfax_prn_open(gx_device *pdev)
  163. {
  164.     gx_device_dfax    *ddev = (gx_device_dfax *) pdev;
  165.     int        rc;
  166.  
  167.     rc = gdev_prn_open(pdev);
  168.     ddev->fax = faxout_open_fp(ddev->file);
  169.     return (rc);
  170. }
  171.  
  172. private int
  173. dfax_print_page(gx_device_printer *pdev, FILE *prn_stream)
  174. {
  175.     gx_device_dfax    *ddev = (gx_device_dfax *) pdev;
  176.     char        data[LINE_SIZE + 4];
  177.     int        lnum;
  178.     int        line_size;
  179.     FAXOUT        *fax = ddev->fax;
  180.  
  181.     /* For some odd reason, the file isn't open until now */
  182.     fax->fp = prn_stream;    
  183.     faxout_begin_page(fax, ddev->y_pixels_per_inch > 120);
  184.     
  185.     line_size = gdev_mem_bytes_per_scan_line( (gx_device *) pdev);
  186.     for ( lnum = 0; lnum < pdev->height; lnum++ )
  187.     {
  188.         gdev_prn_copy_scan_lines(pdev, lnum, (byte *)data, line_size);
  189.         tofax(fax, data, 1728);
  190.     }
  191.     faxout_end_page(fax);
  192.     return 0;
  193. }
  194.  
  195. private int
  196. dfax_prn_close(gx_device *pdev)
  197. {
  198.     gx_device_dfax    *ddev = (gx_device_dfax *) pdev;
  199.     int        rc;
  200.     FAXOUT        *fax = ddev->fax;
  201.     unsigned short     p = fax_ushort(fax->pages);
  202.  
  203.     if (fax->fp)
  204.     {
  205.         fflush(fax->fp);
  206.         if (fseek(fax->fp, (long) OFFSET_PAGES, 0) == 0)
  207.             fwrite((char*)&p, sizeof(p), 1, fax->fp);
  208.     }
  209.     rc = gdev_prn_close(pdev);
  210.     return(rc);
  211. }
  212.  
  213. /*************************************************************************
  214.     Internal routines
  215.  *************************************************************************/
  216.  
  217. /************************Coding FAX Routines*************************/
  218. /*
  219.  *    faxp = faxout_open(filename);
  220.  *    faxp = faxout_open_fp(fp);
  221.  *    faxout_begin_page(faxp, resolution);
  222.  *    for(;;) tofax(faxp, linebuf);
  223.  *    faxout_end_page(faxp);
  224.  *    faxout_close(faxp);
  225.  */
  226.  
  227. private FAXOUT    *
  228. faxout_open_fp(FILE *fp)
  229. {
  230.     register FAXOUT    *faxp;
  231.  
  232.     faxp = (FAXOUT *) malloc(sizeof(*faxp));
  233.  
  234.     faxp->fp = fp;
  235.     faxp->fax_byte = 0;
  236.     faxp->fax_weight = 0x80;
  237.     faxp->pages = 0;
  238.  
  239.     return (faxp);
  240. }
  241.  
  242. private FAXOUT    *
  243. faxout_open(char *filename)
  244. {
  245.     register FILE    *fp;
  246.     register FAXOUT    *faxp;
  247.  
  248.     if (filename)
  249.         fp = fopen(filename, "wb");
  250.     else
  251.         fp = stdout;
  252.     if (!fp) return (NULL);
  253.  
  254.     return(faxout_open_fp(fp));
  255. }
  256.  
  257. private int
  258. faxout_begin_page(FAXOUT *faxp, int resolution)
  259. {
  260.     FAXHDR    hdr;
  261.  
  262.     memset(&hdr, 0, sizeof(hdr));
  263.     memcpy(hdr.id.magic, FAXMAGIC, sizeof(hdr.id.magic));
  264.     hdr.info.pagenum = fax_ushort(++faxp->pages);
  265.     hdr.info.msbfirst = 1;
  266.     hdr.info.hires = resolution;
  267.     hdr.jtinfo.jthires = resolution ? 0x40 : 0;
  268.     fwrite((char*)&hdr, sizeof(hdr), 1, faxp->fp);
  269.  
  270.     puteol(faxp);
  271.  
  272.     return (0);
  273. }
  274.  
  275. private int
  276. faxout_end_page(FAXOUT *faxp)
  277. {
  278.     flushbits(faxp);
  279.     puteol(faxp);
  280.     puteol(faxp);
  281.     puteol(faxp);
  282.     puteol(faxp);
  283.     puteol(faxp);
  284.     flushbits(faxp);
  285.     return (0);
  286. }
  287.  
  288. private int
  289. faxout_close(FAXOUT *faxp)
  290. {
  291.     unsigned short p = fax_ushort(faxp->pages);
  292.  
  293.     fflush(faxp->fp);
  294.     if (fseek(faxp->fp, (long) OFFSET_PAGES, 0) == 0)
  295.         fwrite((char*)&p, sizeof(p), 1, faxp->fp);
  296.     fclose(faxp->fp);
  297.     free(faxp);
  298.  
  299.     return (0);
  300. }
  301.  
  302. private unsigned short
  303. fax_ushort(unsigned short v)
  304. {
  305.     static unsigned short    x = 0x1122;
  306.     static unsigned short    *xp = &x;
  307.     
  308.     if ( *((unsigned char *)xp) == 0x22)
  309.         return (v);
  310.     else
  311.         return ( ((v>>8)&255) + (v<<8) );
  312. }
  313.  
  314. private unsigned char    b_run_tbl[8][256] =
  315. {
  316.   {    /* START BIT 0 */
  317.     0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 
  318.     0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 
  319.     0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 
  320.     0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 
  321.     0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 
  322.     0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 
  323.     0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 
  324.     0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 
  325.     0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 
  326.     0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 
  327.     0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 
  328.     0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 
  329.     0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 
  330.     0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1